<template>
  <div
    ref="target"
    class="w-full relative rounded-lg select-none heading-s-medium"
  >
    <div
      class="text-c-grey-xl outline outline-1 cursor-pointer rounded-lg py-[10px] px-4 hover:outline-c-grey-large bg-c-white"
      :class="[
        { 'outline-c-grey-large': active },
        { 'outline-c-grey-xs': !active }
      ]"
      @click="active = !active"
    >
      <div class="flex gap-2 items-center">
        <span
          class="grow"
          :class="{
            'text-c-grey-3xl':
              placeholderCounterActiveCheckboxes || placeholderActiveRadio
          }"
        >
          <p
            v-if="
              placeholderCounterActiveCheckboxes > 1 ||
              (!placeholderCounterActiveCheckboxes && !placeholderActiveRadio)
            "
          >
            {{ placeholder }}
          </p>
          <p
            v-else-if="placeholderCounterActiveCheckboxes === 1"
            class="max-w-[150px] truncate"
          >
            {{ selectedCheckboxes[0] }}
          </p>
          <p v-else>{{ placeholderActiveRadio }}</p>
        </span>
        <span
          v-if="placeholderCounterActiveCheckboxes === 1"
          class="bg-c-grey-2xs px-2 rounded-xl"
        >
          <SvgoCloseIcon
            class="cursor-pointer text-c-grey-medium hover:text-c-grey-large mt-0.5"
            filled
            @click.stop="handleUpdateCheckboxSelectState"
        /></span>
        <span
          v-if="placeholderCounterActiveCheckboxes > 1"
          class="flex gap-2 items-center text-c-grey-xl bg-c-grey-2xs px-2 rounded-xl truncate"
          >{{ placeholderCounterActiveCheckboxes }}
          <SvgoCloseIcon
            class="cursor-pointer text-c-grey-medium hover:text-c-grey-large mt-0.5"
            filled
            @click.stop="handleUpdateCheckboxSelectState"
        /></span>
        <SvgoArrow
          class="scale-150"
          :class="[
            { 'text-c-grey-large': !active },
            { 'text-c-grey-xl rotate-180': active }
          ]"
          filled
        />
      </div>
    </div>
    <div
      v-if="active"
      class="absolute bg-c-white w-[332px] right-0 z-10 shadow-dropdown-s rounded-xl p-2 pr-0.5 mt-1 max-h-[330px] overflow-y-hidden overflow-x-auto"
      :class="{ 'pt-0': filterable }"
    >
      <div
        v-if="filterable || enableSelectAll"
        class="bg-c-white pr-4"
        :class="{ 'pt-2': filterable }"
      >
        <MoleculeSearchInput
          v-if="filterable"
          v-model="searchValue"
          placeholder="Поиск..."
          class="mb-[6px]"
        />
        <div
          v-if="searchValue && computedOptions.length === 0"
          class="heading-s-medium text-c-grey-large mt-3 ml-3"
        >
          Ничего не найдено
        </div>
        <AtomCheckbox
          v-if="checkbox && enableSelectAll && !searchValue"
          v-model:checked="enableSelectAllState"
          label="Выбрать все"
          name="Select all"
          value="Select all"
          @update:checked="handleSelectAll"
        />
      </div>
      <div
        ref="optionsSelectionRef"
        class="relative max-h-[220px] overflow-y-auto pr-2"
      >
        <MoleculeCheckboxGroup
          v-if="checkbox"
          :value="selectedCheckboxes"
          :options="computedOptions"
          :name="name"
          @update:value="handleUpdateCheckboxSelectState"
        />
        <MoleculeRadioGroup
          v-if="radio"
          :value="selectedRadio"
          :options="options"
          :name="name"
          @update:value="handleUpdateRadioSelectState"
        />
      </div>
      <slot name="options" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { useFilterStore } from '~/stores/filterStore'

interface Props {
  placeholder?: string
  filterable?: boolean
  radio?: boolean
  checkbox?: boolean
  selectedCheckboxes?: any[]
  selectedRadio?: string
  options?: { label: string; value: string }[]
  name?: string
  enableSelectAll?: boolean
}
const active = ref(false)
const searchValue = ref('')
const placeholderCounterActiveCheckboxes = ref(0)
const placeholderActiveRadio = ref('')
const enableSelectAllState = ref(false)
const target = ref(null)

// close selection when click outside
onClickOutside(target, () => {
  active.value = false
  searchValue.value = ''
})

const props = withDefaults(defineProps<Props>(), {
  placeholder: 'Placeholder',
  selectedCheckboxes: () => [],
  selectedRadio: '',
  checkbox: false,
  radio: false,
  options: () => [],
  name: '',
  filterable: false,
  enableSelectAll: false
})

const emits = defineEmits(['update:selectedCheckboxes', 'update:selectedRadio'])
const {
  placeholder,
  filterable,
  radio,
  checkbox,
  selectedCheckboxes,
  selectedRadio,
  options,
  name,
  enableSelectAll
} = toRefs(props)
const optionsSelectionRef = ref(null)
const filterStore = useFilterStore()
const pageSize = 6
const lastPage = computed(() => Math.ceil(options.value.length / pageSize))
const nextPage = ref(2)
const computedOptions = computed(() => {
  if (searchValue.value) {
    const filteredArr = options.value
      .filter((opt) =>
        opt.label.toLowerCase().includes(searchValue.value.toLowerCase().trim())
      )
      .slice(0, pageSize * (nextPage.value - 1))
    return filteredArr
  } else {
    return options.value.slice(0, pageSize * (nextPage.value - 1)) // we need to unref our ref here, because computed return's ref
  }
})

const { arrivedState } = useScroll(optionsSelectionRef)
const { bottom } = toRefs(arrivedState)

// достигли дна - подгружаем новые данные списка
watch(bottom, () => {
  if (bottom.value) {
    if (nextPage.value <= lastPage.value) {
      nextPage.value += 1
    }
  }
})
// закрыли выпадашку - очишаем список подгруженных опций
watch(active, () => {
  if (!active.value) {
    nextPage.value = 2
  }
})

watch(selectedCheckboxes, () => {
  if (selectedCheckboxes.value.length === options.value.length) {
    enableSelectAllState.value = true
  } else {
    enableSelectAllState.value = false
  }
})

const handleUpdateCheckboxSelectState = (updateValue: any[]) => {
  if (Array.isArray(updateValue)) {
    emits('update:selectedCheckboxes', updateValue)
    placeholderCounterActiveCheckboxes.value = updateValue.length
  } else {
    emits('update:selectedCheckboxes', [])
    placeholderCounterActiveCheckboxes.value = 0
  }
}

const handleUpdateRadioSelectState = (updateValue: string) => {
  if (updateValue === 'Нет') {
    emits('update:selectedRadio', updateValue)
    placeholderActiveRadio.value = ''
  } else {
    emits('update:selectedRadio', updateValue)
    placeholderActiveRadio.value =
      filterStore.sort.find((el) => el.sortType === updateValue).sortNameRu ||
      ''
  }
}

const handleSelectAll = (e: boolean) => {
  if (e) {
    const selectedAll = [...options.value.map((opt) => opt.value)]
    emits('update:selectedCheckboxes', selectedAll)
    placeholderCounterActiveCheckboxes.value = options.value.length
  } else {
    emits('update:selectedCheckboxes', [])
    placeholderCounterActiveCheckboxes.value = 0
  }
}
</script>

<style scoped></style>
